/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *	  http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.milib.dbg {
	import com.googlecode.milib.MILibMain;
	import com.googlecode.milib.base.IMLBroadcasterListener;
	import com.googlecode.milib.base.MLBaseClass;
	import com.googlecode.milib.service.singleton.KeyboardService;
	import com.googlecode.milib.service.singleton.MouseService;
	import com.googlecode.milib.util.MLMCUtil;
	import com.googlecode.milib.vo.MLEventInfo;

	import flash.display.CapsStyle;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.JointStyle;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	/**
	 * @author Marek Brun
	 */
	public class MouseObjectSelector extends MLBaseClass implements IMLBroadcasterListener {

		private var ms:MouseService;
		private var root:DisplayObjectContainer;
		private var objects:Array;
		private var ks:KeyboardService;
		private var border:MovieClip;
		private var currentSelectedObject:DisplayObject;
		private var tf:TextField;
		private var deep:Number=0;
		private var isSelected:Boolean;
		
		public function MouseObjectSelector() {
			ms=MouseService.getInstance();
			ks=KeyboardService.getInstance();
			ks.addListener(this);
			root=MILibMain.getInstance().getRoot();
			
			border=new MovieClip();
			border.filters=[new GlowFilter(0, .2, 2, 2, .5)];
			tf=new TextField();
			tf.embedFonts=false;
			var format:TextFormat=new TextFormat('Tahoma', 10, 0);
			tf.setTextFormat(format);
			tf.autoSize=TextFieldAutoSize.LEFT;
			tf.background = true;			tf.border = true;
			border.addChild(tf);
			tf.text='H';
			tf.y=-tf.height;
		}
		
		protected function selectObject(disp:DisplayObject):void {
			if(currentSelectedObject==disp){ return; }
			currentSelectedObject=disp;
			if(!border.parent){
				root.addChild(border);
			}
			var bounds:Rectangle=disp.getBounds(root);
			border.x=bounds.x;
			border.y=bounds.y;
			border.graphics.clear();
			border.graphics.lineStyle(2, 0xFFFF00, 1, true, null, CapsStyle.SQUARE, JointStyle.MITER);
			border.graphics.moveTo(0, 0);
			border.graphics.lineTo(0+bounds.width, 0);
			border.graphics.lineTo(0+bounds.width, 0+bounds.height);
			border.graphics.lineTo(0, bounds.height);
			border.graphics.lineTo(0, 0);
			var parents:Array=[disp].concat(MLMCUtil.getParents(disp));
			var i:uint;
			for(i=0;i<parents.length;i++){
				if(parents[i]==disp){
					parents[i]='<b>'+parents[i].name+'</b>';
				}else{
					parents[i]=parents[i].name;
				}
				
			}
			tf.htmlText=parents.join('.');
			tf.y=-tf.height;
			if(MLMCUtil.getYRoot(tf)<0){
				MLMCUtil.setYRoot(tf, 0);
			}
		}
		
		protected function deselectObject():void {
			isSelected=false;
			if(border.parent){
				root.removeChild(border);
			}
			currentSelectedObject=null;
		}
		
		protected function selectObjectUnderCurrentPoint():void {
			objects=root.getObjectsUnderPoint(new Point(root.mouseX, root.mouseY));
			objects.reverse();
			if(objects.length) {
				var parents:Array=[objects[0]].concat(MLMCUtil.getParents(objects[0]));
				if(parents[deep]){
					selectObject(parents[deep]);
				}else{
					deep=parents.length-1;
					selectObject(parents[parents.length-1]);
				}
			}else{
				deselectObject();
			}
		}
		
//********************************************************************************************
//		events for MouseObjectSelector
//********************************************************************************************
		public function onEvent(ev:MLEventInfo):void {
			switch(ev.hero){
				case ks:
					switch(ev.event) {
						case ks.event_Down:
							switch(ev.data.keyCode) {
								case KeyboardService.KEY_N:
									if(ks.getIsKeyDown(KeyboardService.KEY_TILDE)){
										isSelected=true;
										ms.addListener(this);
										selectObjectUnderCurrentPoint();
									}
								break;
							}
						break;
						case ks.event_Up:
							if(isSelected){
								ms.removeListener(this);
								deselectObject();
							}
						break;
					}
				break;
				case ms:
					switch(ev.event) {
						case ms.event_Move:
							deep=0;
							selectObjectUnderCurrentPoint();
						break;
						case ms.event_Down:
							if(!currentSelectedObject){ break; }
							MLDBG.getInstance().openObjectWindow(currentSelectedObject);
						break;
						case ms.event_Whell:
							var mouseEvent:MouseEvent=ev.data as MouseEvent;
							if(mouseEvent.delta>=0){
								deep=Math.max(0, deep+1);
							}else{
								deep=Math.max(0, deep-1);
							}
							selectObjectUnderCurrentPoint();
						break;
					}
				break;
			}
		}
		
		
	}

}
